﻿using System;
using System.Text;

namespace mklib.json
{
	/// <summary>
	/// Json相关工具
	/// </summary>
	internal static class JsonHelper
	{
		/// <summary>
		/// 将对象转换为IJsonValue
		/// </summary>
		/// <returns>The JS value.</returns>
		/// <param name="o">转换对象</param>
		/// <param name="depth">IJsonValue树深度</param>
		internal static IJsonValue GetJSValue(object o, int depth)
		{
			if (o == null)
				return new JsonValue (null, JsonValueType.Null, null, depth);

			JsonValueType t = JsonTypeConvertor.GetJSType (o.GetType());
			if (t == JsonValueType.Object && o is Array) {
				t = JsonValueType.Array;
			}
			if (t == JsonValueType.Array) {
				JsonValueArray arr = new JsonValueArray (depth);
				Array a = o as Array;
				foreach (var obj in a) {
					IJsonValue val = GetJSValue (obj, depth + 1);
					arr.Add (val);
				}
				return arr;
			}
			var V = new JsonValue (o, t, null, depth);
			return V;
		}

		/// <summary>
		/// JavaScript起始时间对应C#时间戳
		/// </summary>
		internal const long JavaScriptTimeStart = 621355968000000000;

		internal static double ToJavaScriptTimeticks(DateTime t)
		{
			return (t.ToUniversalTime ().Ticks - JavaScriptTimeStart) / (double)10000;
		}
		internal static DateTime ToDateTime(double jsTicks)
		{
			long ticks = (long)(jsTicks * 10000);
			var datetime = new DateTime(ticks + JsonHelper.JavaScriptTimeStart).ToLocalTime();
			return datetime;
		}

		/// <summary>
		/// 去掉换行符
		/// </summary>
		/// <returns>The parse string.</returns>
		/// <param name="s">S.</param>
		internal static string SerializeString(string s)
		{
			if (String.IsNullOrEmpty (s))
				return String.Empty;
			return s.Replace ("\n", "\\n").Replace ("\r", "\\r");
		}

		internal static string UnSerializeString(string s)
		{
			if (String.IsNullOrEmpty (s))
				return String.Empty;
			return s.Replace ("\\n", "\n").Replace ("\\r", "\r");
		}

		/// <summary>
		/// 标准化字符串
		/// </summary>
		/// <returns>The string.</returns>
		/// <param name="s">S.</param>
		internal static string FormatString(string s)
		{
			if (String.IsNullOrEmpty (s))
				return String.Empty;
			return SerializeString(s)
				.Replace ("\"", "\\\"")
				.Replace ("\\", "\\\\")
				.Replace ("/", "\\/")
				;
		}

		/// <summary>
		/// 恢复字符串原貌
		/// </summary>
		/// <returns>The format string.</returns>
		/// <param name="s">S.</param>
		internal static string UnFormatString(string s)
		{
			if (String.IsNullOrEmpty (s))
				return String.Empty;
			s = UnSerializeString(
				s.Replace ("\\/", "/")
				.Replace ("\\\\", "\\")
				.Replace ("\\\"", "\"")
			);
			return s;
		}

		/// <summary>
		/// 重复字符串
		/// </summary>
		/// <returns>The string.</returns>
		/// <param name="s">原始字符串</param>
		/// <param name="count">重复次数</param>
		internal static string RepeatString(string s, int count)
		{
			if (count <= 0 || String.IsNullOrEmpty (s))
				return String.Empty;
			StringBuilder b = new StringBuilder ();
			while (count > 0) {
				b.Append (s);
				count--;
			}
			return b.ToString ();
		}

		internal static object ConvertValue(object val, Type t)
		{
			if (t == typeof(DateTime) && val is double) {
				return ToDateTime ((double)val);
			} else if (t == typeof(String) && val is String) {
				return UnFormatString ((string)val);
			}
			return val;
		}
	}
}

